home *** CD-ROM | disk | FTP | other *** search
- Thrustmaster Application Note AN-0001
- Advanced Key Programming Techniques for the FLCS
- Copyright (c) 1995 Thrustmaster, Inc.
- All Rights Reserved
-
- Introduction
- ------------
-
- The FLCS provides a comprehensive set of key functions which directly
- handle the majority of the keying requirements for most games by simply
- listing the keystrokes required. Situations do arise, however, that
- require some non-standard handling. This note describes the built-in
- functions in some detail, and also outlines the various techniques
- that can be used when the built-in functions are not sufficient to
- handle the requirement at hand.
-
- Keyboard Basics
- ---------------
-
- Programming the FLCS to perform a particular function is basically a
- matter of getting it to send the right sequence of keycodes to the PC.
- While the FLCS takes care of this for most of the standard keys and
- functions, advanced techniques require a basic understanding of how
- the keyboard itself interacts with the PC.
-
- The keyboard operates by sending 'Make' and 'Break' codes to the PC.
- These 'codes' are sequences of one or more data bytes. They are not
- 'ASCII Characters', but just indicate which keys have been moved.
- When you press a key, the 'Make' code is sent. When you release the
- key, the 'Break' code is sent. Each key on the keyboard has a unique
- sequence of codes assigned to it for its 'Make' and 'Break' sequences.
-
- The PC can't actually determine whether a key is pressed or released
- at any particular time. Rather, it simply keeps track of the 'Make'
- and 'Break' codes. When it receives a 'Make' code, it flags the key
- as pressed until it receives the corresponding 'Break' code, at which
- time it flags the key as released.
-
- Since the sequencing of the 'Make' and 'Break' codes is important to
- the following discussion, it will be convenient to adopt some notation
- for them. In what follows, the '+' character will be used to indicate
- the 'Make' code for a key, and the '-' character will be used to
- indicate the 'Break' code. For instance:
- +a -a
-
- would indicate the press and subsequent release of the 'a' key.
-
- Combinational Keypresses
- ------------------------
-
- Generating single keypresses or strings of single keypresses with the
- FLCS is a straightforward process. The desired characters are simply
- listed in the BTN statement. There are several situations, though, that
- require that multiple keys be pressed simultaneously, and these can
- create problems. The correct programming method is often not clear as
- it depends on how the game processes the keystrokes. The remainder of
- this note will attempt to explain the different techniques available
- and when these techniques should be used.
-
- SHF, ALT, and CTL
- -----------------
-
- The most common form of simultaneous keypress is when it is necessary
- to generate a modified key like CTRL-C, ALT-J, or even 'A', since the
- upper cased character implies that the SHF key is held down while the
- key is pressed. It is generally a simple matter to program these
- combinations with the FLCS, you simply precede the character with the
- appropriate modifier:
-
- BTN S1 CTL c
-
- Any time you specify and upper case character, the FLCS generates the
- SHF code for you, so;
-
- BTN S1 A
-
- is actually treated as:
-
- BTN S1 SHF a
-
- and the key sequence generated is:
-
- +SHF +a -SHF -a
-
- It is worth noting that only the SHF, CTL, and ALT keywords are
- treated as modifiers. The variations that specify particular keys,
- such as LALT and RSHF are treated as regular keys. So if you program
- something like:
- BTN S1 LALT j
-
- the sequence that is generated is:
-
- +LALT -LALT +j -j
-
- and an actual ALT-J combination does not occur. Programming it as:
-
- BTN S1 ALT j
-
- produces the desired:
-
- +ALT +j -ALT -j
-
- Simultaneous Groups
- -------------------
-
- As noted in the FLCS manual, if you enclose a set of characters in
- 'curly brackets' it causes the ordering of 'Make' and 'Break' codes to
- be modified so that the keys in the group are pressed simultaneously:
-
- BTN S1 {a b c}
-
- will send the sequence:
- +a +b +c -a -b -c
-
-
- This function is useful when two or more keys need to be pressed at
- the same time, but it does not hold the keys down for any appreciable
- length of time. They are pressed and then immediately released. The
- simultaneous group is also useful where a game requires a particular
- SHF or ALT key to be used. The normal SHF, ALT, and CTL modifiers
- always use the codes for the Left key, i.e. LSFT. If you needed 'Right
- Shift x' you could program it as:
-
- BTN S1 {RSFT x}
-
- and force the use of the Right Shift key. The generated sequence would
- be:
- +RSFT +x -RSFT -x
-
-
- Repeating Keypresses
- --------------------
-
- It frequently becomes necessary in FLCS programming to generate keys
- that are 'held down' to achieve some particular function. Normally this
- can be done by just specifying a single character as a repeating key:
-
- BTN S1 a
-
- This generates a sequence of multiple 'Make' codes while the button
- is held down, and generates a single 'Break' code when the button is
- released.
-
- This is essentially what the keyboard does, but there is one fundamental
- difference. When another button is pressed and the FLCS sends another
- character, the FLCS will send a 'Break' code for the repeating character,
- even if the button (S1 in this example) is still held down. The keyboard
- does not send the 'Break' code until the key is released. For example,
- if you programmed:
- BTN S1 a
- BTN S2 b
-
- then pressed S1, pressed S2, released S2, and then released S1, the FLCS
- would generate something like:
-
- +a +a +a +a -a +b +b +b +b -b
-
- whereas if you did the same thing on the keyboard using the actual 'a'
- and 'b' keys, the sequence would look like this:
-
- +a +a +a +a +b +b +b +b -b -a
-
- The FLCS was coded this way on purpose. When you're using the keyboard,
- you are generally aware of which keys you've got pressed at any particular
- time, and inappropriate combinations don't occur very often. When you're
- using the FLCS, it's not always apparent what keys you are pressing. For
- example, look at the program segment:
-
- BTN S1 A
- BTN S2 b
-
- If the FLCS actually emulated the keyboard, the generated sequence would
- be:
-
- +SHF +a +a +a +a +b +b +b +b -b -SHF -a
-
- If you pressed them in the order outlined for the first example. If you
- looked at this on the screen, you would see 'AAAABBBB', rather than the
- 'AAAAbbbb' that you would expect, since the SHF key has not been released.
- Forcing the 'Break' when S2 is pressed changes the sequence to:
-
- +SHF +a +a +a +a -SHF -a +b +b +b +b -b
-
- which is more in keeping with the intent of the program. This is a fairly
- simple example, worse problems could occur. If S1 were defined as 'ALT a',
- then so long as S1 were held, the PC would see every key coming at it as
- having the ALT modifier added, i.e. you'd not only get 'ALT a' like you
- wanted, you'd get 'ALT b', too, since the ALT would still be down from
- the S1 press. Disastrous combinations could occur, consider what might
- happen if a program contained something like:
-
- BTN S1 CTL a
- BTN S2 ALT j
- BTN S3 DEL
-
- and all three buttons were pushed. The PC would see a simultaneous press
- of CTL-ALT-DEL, and would likely reboot. Probably not exactly what you
- wanted to happen.
-
- Hold Codes
- ----------
-
- In some circumstances, it is necessary to hold the key down even when
- other buttons are pressed. The most common examples are keys that move
- control surfaces, and situations that require multiple keys to be held
- to achieve a particular view. For instance, suppose you wanted to program
- a hat to control the rudders. You might try (assuming 'l' and 'r' are
- the left and right rudder keys respectively)
-
- BTN H1L l
- BTN H1R r
-
- This would activate the rudders, but because of the way the repeating
- keys operate on the FLCS, as soon as you pushed another button the rudder
- would return to it's neutral position. The use of the /H code would get
- around the problem, since it does not generate a 'Break' until the Hat
- is released. The coding would look like this:
-
- BTN H1L /H l
- BTN H1R /H r
-
- The /H codes are also slightly different in the way they appear on the
- screen. There is only a single 'Make' code generated, so you only see
- one character when you press the button. The PC will see the key as held,
- however, and in situations where the /H is required, the absence of the
- repeated 'Make' codes is of no consequence. The game will be looking
- only at the first 'Make' code in such situations, anyway.
-
- Holding down multiple keys is simply a matter of adding them to the
- list. To hold down KP8 and KP5 for a combinational view, the program
- would look like this:
- BTN H1U KP8 KP5
-
- When the button was pressed, the sequence generated would be:
-
- +KP8 +KP5
-
- and when the button was released, the sequence would be:
-
- -KP8 -KP5
-
- Any characters generated by other buttons while H1U was held would be
- sent normally,
-
- While /H codes are very useful, they are not without a few problems.
- First, as mentioned earlier in the discussion of repeating keys, it's
- generally not possible to use them for anything other than unmodified
- keys. The use of upper-case, SHF, ALT or CTL modifiers creates problems
- in that the PC will apply those modifiers to all characters transmitted
- while the /H is held down, i.e.
-
- BTN S1 /H A
-
- will upper-case all keys transmitted while S1 is pressed. Consequently,
- the use of such modifiers must generally be avoided in /H groups.
-
- A second limitation places on /H groups is that they cannot be used
- with the /I and /O, or the /U, /M, and /D modifiers. The reason for
- this is not immediately obvious, but to have allowed them to be used
- there would create a strong likelihood of 'stuck' keys during operation.
- Consider the following example:
-
- BTN S1 /O /H a
- /I /H b
-
- Now suppose that during game play, you were to press S1, then press S3,
- then release S1. Since S3 was not pressed initially, the /O side of the
- definition would be in control. The initial press of S1 would send the
- 'Make' code for the 'a' as expected. When S3 was pressed, that would
- put the /I side of the definition in control. Subsequently releasing
- S1 would result in the 'Break' break code for the 'b' being sent. The
- sequence at the PC would be:
- +a -b
-
- The PC has seen the 'a' pressed, but never sees it released, so it will
- it considersit to be still pressed. The key is 'stuck', and will remain
- that way until a 'Break' for the 'a' is sent, either by hitting the 'a'
- on the keyboard, or sending a complete 'a' with the FLCS. It will remain
- stuck even if you exit the game.
-
- The limitation on the /I, /O, /U, /M/ and /D codes can be overcome in a
- couple of ways. One is simply to come up with a scheme that doesn't need
- them. The use of the /I and /O codes with held characters most commonly
- shows up in view switching situations. One method that works in some
- situations is to just use unmodified views on the hat, then add the
- modifier key to button S3. For example, suppose that the four basic
- views are KP8, KP6, KP2, and KP4. Also assume that adding KP5 to these
- four will add the UP modifier, and that adding KP0 to them will add the
- DOWN modifier, i.e. KP4 is Look Left and KP4 + KP5 is Look Up and Left.
- In that case, a setup like this:
-
- BTN H1U /H KP8
- BTN H1L /H KP4
- BTN H1D /H KP2
- BTN H1R /H KP6
-
- BTN S3 /H KP5
- BTN S4 /H KP0
-
- may prove workable, giving 12 views via combinations of the hat and the
- S3 and S4 keys.
-
- If you can't find a suitable setup using the standard functions, you can
- probably get around the problem using the RAW data codes.
-
- RAW Data Codes
- --------------
-
- RAW data codes allow you complete control over what the FLCS sends to
- the PC. You specify the actual codes sent to the PC by their hex values.
- There are no real limits placed on the use of RAW codes, they can be
- used within the /I-/O and /U-/M-/D groups, and so you can generate any
- key sequence that you want to. A complete listing of the RAW sequences
- for the 'Make' and 'Break' codes on the 101-Key Keyboard is listed at
- the end of this note.
-
- The RAW data function was designed for situations where the normal FLCS
- functions would not handle the task at hand. The most common use of
- them is to generate the so-called 'non-native' keys that the FLCS will
- not normally transmit. If you look over the RAW codes chart, you'll see
- that the majority of keys send a single RAW code for a 'Make', and send
- the value '#F0' followed by that same RAW code for the 'Break'. These
- are the 'native' keys, and they correspond roughly to the keys on the
- older 84-Key AT keyboards. The other 'non-native' keys are primarily
- associated with the 101-Key Keyboard, and usually have an extra '#E0'
- added to the sequence. These keys include the auxiliary 'T-Cursor' pad
- and the other keys in the section of the 101-Key Keyboard between the
- main keys and the numeric pad.
-
- The other primary use of the RAW codes is to generate key combinations
- that cannot normally be generated by the FLCS, such as the use of held
- characters within /I-/O and /U-/M-/D Groups. The basic method for
- simulating a /H group is to generate a /P-/R set with the 'Make' codes
- on the /P side and the 'Break' codes on the /R side. For instance:
-
- BTN S1 /P RAW(#1C)
- /R RAW(#F0 #1C)
-
- produces the same output as:
-
- BTN S1 /H a
-
- with the 'Make' code sent when the button is pressed and the 'Break'
- code being sent when it's released.
-
- As mentioned earlier, using RAW codes within the /I-/O and /U-/M-/D
- groups is permitted, but it does not get around the basic problem with
- the 'stuck' keys. You have to set the programming up so that the problem
- does not occur. The usual method is to include the 'Make' codes for a
- single function on the /P side, and to include the 'Break' codes for all
- possible functions on the /R side. This is generally possible since
- multiple 'Make' codes for a key generally do no harm, and 'Break' codes
- for keys that have not been 'Made' are generally possible. For example.
- the program segment:
-
- would not compile, but the equivalent:
-
- BTN H1U /O /P RAW(#2B #34) rem Make 'f' and 'g'
- /R RAW(#F0 #28 #F0 #34) rem Break f, g
- /I /P RAW(#73 #75) rem Make KP5 and KP8
- /R RAW(#F0 #F0 #73 #F0 #75) rem Break f, g, KP5 & KP8
-
- would compile just fine. This does not avoid the stuck key problem
- though. You need to 'Break' both possibilities on both sides, even
- though you will only 'Make' one of the codes:
-
- BTN H1U /O /P RAW(#2B #34) rem Make 'f' and 'g'
- /R RAW(#F0 #28 #F0 #34 #F0 #73 #F0 #75) rem Break f, g, KP5 & KP8
- /I /P RAW(#73 #75) rem Make KP5 and KP8
- /R RAW(#F0 #28 #F0 #34 #F0 #73 #F0 #75) rem Break f, g, KP5 & KP8
-
- One thing to watch for here is that all those RAW codes take some time
- to send, about 50% longer than a regular /H group. The best thing to do
- is to set the RATE parameter down to 0, increase it only if you experience
- problems with the game in question. Most of the games will work just fine
- with a RATE of 0, the exceptions are games that only handle 1 key stroke
- per frame.
-
- A couple of things worth mentioning. You can send sequences with RAW codes
- that will hang the keyboard. As long as you stick with the codes that are
- listed and get all the 'Makes' and 'Breaks' lined up, there's no problem,
- but you might need to reboot if you get them wrong. Also, you need to be
- aware of what combinations you generate with held keypresses, either with
-
-
-
- -----------------------------------------------------------------------------
-
- *** STANDARD 101-KEY KEYBOARD SCAN CODE SEQUENCES ***
- For Use with the FLCS 'RAW' Programming Function
-
- ** Main Keyboard **
- ----------------------------------------------------------------------------
- Key Make Code Break Code Notes
- ----------------------------------------------------------------------------
- ` #0E #F0 #0E
- 1 #16 #F0 #16
- 2 #1E #F0 #1E
- 3 #26 #F0 #26
- 4 #25 #F0 #25
- 5 #2E #F0 #2E
- 6 #36 #F0 #36
- 7 #3D #F0 #3D
- 8 #3E #F0 #3E
- 9 #46 #F0 #46
- 0 #45 #F0 #45
- - #4E #F0 #4E
- = #55 #F0 #55
- Backspace #66 #F0 #66
-
- Tab #0D #F0 #0D
- Q #15 #F0 #15
- W #1D #F0 #1D
- E #24 #F0 #24
- R #2D #F0 #2D
- T #2C #F0 #2C
- Y #35 #F0 #35
- U #3C #F0 #3C
- I #43 #F0 #43
- O #44 #F0 #44
- P #4D #F0 #4D
- [ #54 #F0 #54
- ] #5B #F0 #5B
- \ #5D #F0 #5D
-
- Caps Lock #58 #F0 #58
- A #1C #F0 #1C
- S #1B #F0 #1B
- D #23 #F0 #23
- F #2B #F0 #2B
- G #34 #F0 #34
- H #33 #F0 #33
- J #3B #F0 #3B
- K #42 #F0 #42
- L #4B #F0 #4B
- ; #4C #F0 #4C
- ' #52 #F0 #52
- Enter #5A #F0 #5A
-
- Left Shift #12 #F0 #12
- Z #1A #F0 #1A
- X #22 #F0 #22
- C #21 #F0 #21
- V #2A #F0 #2A
- B #32 #F0 #32
- N #31 #F0 #31
- M #3A #F0 #3A
- , #41 #F0 #41
- . #49 #F0 #49
- / #4A #F0 #4A
- Right Shift #59 #F0 #59
-
- Left Ctrl #14 #F0 #14
- Left Alt #11 #F0 #11
- Space #29 #F0 #29
- Right Alt #E0 #11 #E0 #F0 #11
- Right Ctrl #E0 #14 #E0 #F0 #14
- ESC #76 #F0 #76
- ----------------------------------------------------------------------------
-
-
- ** Function Keys **
- ----------------------------------------------------------------------------
- Key Make Code Break Code Notes
- ----------------------------------------------------------------------------
- F1 #05 #F0 #05
- F2 #06 #F0 #06
- F3 #04 #F0 #04
- F4 #0C #F0 #0C
- F5 #03 #F0 #03
- F6 #0B #F0 #0B
- F7 #83 #F0 #83
- F8 #0A #F0 #0A
- F9 #01 #F0 #01
- F10 #09 #F0 #09
- F11 #78 #F0 #78
- F12 #07 #F0 #07
- ----------------------------------------------------------------------------
-
-
- ** Numeric Pad **
- ----------------------------------------------------------------------------
- Key Make Code Break Code Notes
- ----------------------------------------------------------------------------
- NumLok #77 #F0 #77
- KP- #7B #F0 #7B
- KP/ #E0 #4A #E0 #F0 #4A Notes 1, 2
- KP. #71 #F0 #71
- KP* #7C #F0 #7C
- KP+ #79 #F0 #79
- KPEnter #E0 #5A #E0 #F0 #5A
-
- KP0 #70 #F0 #70
- KP1 #69 #F0 #69
- KP2 #72 #F0 #72
- KP3 #7A #F0 #7A
- KP4 #6B #F0 #6B
- KP5 #73 #F0 #73
- KP6 #74 #F0 #74
- KP7 #6C #F0 #6C
- KP8 #75 #F0 #75
- KP9 #7D #F0 #7D
- ----------------------------------------------------------------------------
-
-
- ** Auxiliary Pads **
- ----------------------------------------------------------------------------
- Key Make Code Break Code Notes
- ----------------------------------------------------------------------------
- Ins #E0 #70 #E0 #F0 #70 Notes 1, 2, 3
- Home #E0 #6C #E0 #F0 #6C Notes 1, 2, 3
- Pg Up #E0 #7D #E0 #F0 #7D Notes 1, 2, 3
- Del #E0 #71 #E0 #F0 #71 Notes 1, 2, 3
- End #E0 #69 #E0 #F0 #69 Notes 1, 2, 3
- Pg Dn #E0 #7A #E0 #F0 #7A Notes 1, 2, 3
-
- Up Arrow #E0 #75 #E0 #F0 #75 Notes 1, 2, 3
- Left Arrow #E0 #6B #E0 #F0 #6B Notes 1, 2, 3
- Right Arrow #E0 #74 #E0 #F0 #74 Notes 1, 2, 3
- Down Arrow #E0 #72 #E0 #F0 #72 Notes 1, 2, 3
-
- PrtSc #E0 #12 #E0 #7C #E0 #F0 #7C #E0 #F0 #12
- Ctl-PrtSc #E0 #7C #E0 #F0 #7C
- Alt-PrtSc #84 #E0 #84
- ScrLk #7E #F0 #7E
- Pause #E1 #14 #77 #E1 #F0 #14 #77 None
- Ctrl-Break #E0 #7E #E0 #F0 #7E None
-
- ----------------------------------------------------------------------------
-
-
- ** Notes **
- ----------------------------------------------------------------------------
-
- The actual keyboard makes certain modifications to some of the key code
- sequences depending on the Shift and NumLock states. These can normally
- be ignored in using the RAW codes with the FLCS, but are included here
- for completeness. They only apply where there is an entry in the 'Notes'
- column for the key of interest.
-
- The '#** #**' entry represesnts the Make Code and the '#** #** #**' entry
- represents the Break Code specified for the character in the main chart
- and should be replaced with those sequences in actual use.
-
-
- Note 1
-
- If Left Shift is Down:
-
- Make Sequence - #E0 #F0 #12 #** #**
- Break Sequence _ #** #** #** #E0 #12
-
- Note 2
-
- If Right Shift is Down:
-
- Make Sequence - #E0 #F0 #59 #** #**
- Break Sequence - #** #** #** #E0 #59
-
- Note 3
-
- If Num Lock is On:
-
- Make Sequence - #E0 #12 #** #**
- Break Sequence - #** #** #** #E0 #F0 #12
-
- -----------------------------------------------------------------------------
- -- End of Document --
-